#ifndef NLP_MACROS_H_
#define NLP_MACROS_H_

#include "global.h"

#ifndef INT32_MAX
#define INT32_MAX 0x7fffffffL
#endif
#ifndef INT_MAX
#define INT_MAX 0x7fffffffL
#endif
#ifndef INT_MIN
#define INT_MIN -0x7fffffffL
#endif

#ifdef TR1
#define MAKESHARED(type, ...) std::tr1::shared_ptr<type>(new type(__VA_ARGS__))
#else
#define MAKESHARED(type, ...) std::shared_ptr<type>(new type(__VA_ARGS__))
#endif

#ifdef __BLOCKS__
//#import <Foundation/Foundation.h>
#endif

#ifdef TR1
#include <tr1/functional>
#include <tr1/memory>
#endif

#ifdef __BLOCKS__
#include <Block.h>
#else
//#include <pthread.h>

/*namespace stdex {

        class thread {
        private:
                function<void()> func;
                pthread_t pt;
        public:
                static void* threadfunc(void* _f) {
                        auto f = (function<void()>*) _f;
                        (*f)();
                        delete f;
                        //std::cout << "thread exited" << std::endl;
                        pthread_exit(NULL);
                }
                thread(const function<void()>& f) : func(f) {
                        start();
                }
                void start() {
                        auto f = new function<void()>(func);
                        pthread_create(&pt, NULL, &threadfunc, f);
                }
                bool join() {
                        void* status;
                        int rc = pthread_join(pt, &status);
                        //std::cout << "thread joined: " << rc << std::endl;
                        return !rc;
                }
                //~thread() { std::cout << "dealloc (thread)" << std::endl; }
        };

}*/
#endif

#ifndef __BLOCKS__
#define __block
#endif

#ifdef __BLOCKS__
#define BLOCKVAR(var, ret, ...) ret (^var)(__VA_ARGS__)
#else
#define BLOCKVAR(var, ret, ...) function<ret(__VA_ARGS__)> var
#endif

/*#ifdef __BLOCKS__
#define BLOCKARG(var, ret, ...) ret (^var)(__VA_ARGS__)
#else
#define BLOCKARG(var, ret, ...) function<ret(__VA_ARGS__)> var
#endif*/

#ifdef __BLOCKS__
#define BLOCK(...) ^
#define BLOCKRET(ret, ...) ^ret
#define BLOCKBODY(ret)
#else
#define BLOCK(...) [__VA_ARGS__]
#define BLOCKRET(ret, ...) [__VA_ARGS__]
#define BLOCKBODY(ret) -> ret
#endif

/*#ifdef __BLOCKS__
static NSOperationQueue* globalOperationQueue = [[NSOperationQueue alloc] init];
#define DETACHTHREAD(block) [globalOperationQueue addOperation: [NSBlockOperation blockOperationWithBlock: block]]
#else
#define DETACHTHREAD(block) thread(block)
#endif*/

#endif
